package com.myutils;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author Lan
 */
public class HttpClientUtil {

	protected static Log logger = LogFactory.getLog(HttpClientUtil.class);

	public static String charset = "utf-8";
	
	private static String getResponseContent(HttpMethod method) throws IOException{
		return StringUtils.trimToEmpty(method.getResponseBodyAsString());
		/*InputStream respStream = null;
		BufferedReader br = null;
		StringBuilder respBuffer = new StringBuilder();
		try {
			respStream = method.getResponseBodyAsStream();
			br = new BufferedReader(new InputStreamReader(respStream));
			String line = "";
			while((line = br.readLine()) != null){
				respBuffer.append(line);
			}
		} catch (IOException e) {
			throw new IOException(e);
		} finally {
			IOUtils.closeQuietly(br);
			IOUtils.closeQuietly(respStream);
		}
		return respBuffer.toString();*/
	}
	
	/**
	 * 执行一个HTTP GET请求，返回请求响应的字符串
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param queryString
	 *            请求的查询参数,可以为null
	 * @return 返回请求响应的HTML
	 */
	public static String doGet(String url, String queryString) {
		String respStr = "";
		HttpClient client = new HttpClient();
		GetMethod getMethod = new GetMethod(url);
		try {
			if (StringUtils.isNotBlank(queryString))
				getMethod.setQueryString(URIUtil.encodeQuery(queryString));// 汉字编码后，就成为%式样的字符串

			int statusCode = client.executeMethod(getMethod);

			if (statusCode == HttpStatus.SC_OK) {
				respStr = getResponseContent(getMethod);
				logger.debug(url + "的响应内容为: " + respStr);
			} else
				logger.error("Get请求执行失败, HttpStatus : " + getMethod.getStatusLine());

		} catch (URIException e) {
			logger.error("执行Get请求时，编码查询字符串“" + queryString + "”发生异常！", e);
		} catch (IOException e) {
			logger.error("执行Get请求" + url + "时，发生异常！", e);
		} finally {
			getMethod.releaseConnection();
		}
		return respStr;
	}

	/**
	 * 执行一个HTTP POST请求，返回请求响应的字符串
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param params
	 *            请求的查询参数,可以为null
	 * @return 返回请求响应的HTML
	 */
	public static String doPost(String url, Map<String, String> params) {
		String respStr = "";
		PostMethod postMethod = getPostMethod(url);
		try {
			
			if (params != null && params.size() > 0)
				setPostParam(postMethod, params);

			NameValuePair[] arr = postMethod.getParameters();

			logger.debug(url + "的请求参数为：");
			for (NameValuePair nvp : arr) {
				logger.debug(nvp.getName() + "=" + nvp.getValue());
			}

			HttpClient client = new HttpClient();
			int statusCode = client.executeMethod(postMethod);

			if (statusCode == HttpStatus.SC_OK) {
				respStr = getResponseContent(postMethod);
				logger.debug(url + "的响应内容为: " + respStr);
			} else
				logger.error("Post请求执行失败, HttpStatus=" + postMethod.getStatusLine());

		} catch (IOException e) {
			logger.error("执行Post请求" + url + "时，发生异常！", e);
		} finally {
			postMethod.releaseConnection();
		}
		return respStr;
	}

	/**
	 * 使用POST方式提交数据
	 */
	private static HttpMethod setPostParam(PostMethod post, Map<String, String> params) {
		Set<NameValuePair> set = new HashSet<NameValuePair>();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			NameValuePair pair = new NameValuePair(entry.getKey(), entry.getValue());
			set.add(pair);
		}
		NameValuePair[] arr = set.toArray(new NameValuePair[set.size()]);
		post.setRequestBody(arr);
		return post;
	}
	
	/**
	 * 
	 * @author Lan
	 * @param url Post请求的地址
	 * @param content 发送的内容
	 * @param contentType 数据类型：text/xml...
	 * @return
	 */
	public static String doPost(String url, final String content, String contentType) {
		String respStr = "";

		PostMethod postMethod = getPostMethod(url);
		try {
			postMethod.addRequestHeader("Content-type", contentType + "; charset=" + charset);
			postMethod.addRequestHeader("Content-length", content.length()+"");
			
			postMethod.setRequestEntity(new StringRequestEntity(content, contentType, charset));

			HttpClient client = new HttpClient();
			int statusCode = client.executeMethod(postMethod);

			if (statusCode == HttpStatus.SC_OK) {
				respStr = getResponseContent(postMethod);
				logger.debug(url + "的响应内容为: " + respStr);
			} else
				logger.error("Post请求执行失败, HttpStatus=" + postMethod.getStatusLine());

		} catch (IOException e) {
			logger.error("执行Post请求" + url + "时，发生异常！", e);
		} finally {
			postMethod.releaseConnection();
		}
		return respStr;
	}
	
	private static PostMethod getPostMethod(String url){
		PostMethod postMethod = new PostMethod(url);
		HttpMethodParams httpMethodParams = postMethod.getParams();
		// Post编码
		httpMethodParams.setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
		// retry handler
		httpMethodParams.setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
		return postMethod;
	}
}
